#pragma once

#include "MBDataTypes.h"
#include "MBTriangleSightFrustum.h"
#include "MBTriangleSightTriangle.h"
#include "MBVec3.h"

#include <set>
#include <vector>

class MBTriangle;

/**
  * MBMBOctreeNode object representing a cuboid shaped area of space
  */
class MBOctreeNode
{
	friend class MBOctree;

protected:
	MBOctreeNode( const MBVec3 &min, const MBVec3 &max, const MBuint &level, const MBuint &maxLevels );
	~MBOctreeNode( void );

	MBuint GetNumberOfTriangles( void ) const;
	void AddTriangle( const MBuint &triangleIndex, const MBVec3 *trianglePoints );

	bool IsOtherTriangleIntersectingSightFrustum(
		const MBTriangleSightFrustum &sightFrustum,
		const MBuint *triangleVertexIndices,
		const std::vector<MBTriangle*> *triangles,
		const std::vector<double*> *vertexCoordinates );
		//std::set<MBuint> &alreadyCheckedTriangleIndices );

	bool IsOtherTriangleIntersectingSightTriangle(
		const MBTriangleSightTriangle &sightTriangle,
		const MBuint *edgeVertexIndices,
		const std::vector<MBTriangle*> *triangles,
		const std::vector<double*> *vertexCoordinates );

private:
	/** Enum value to indicate the child */
	enum MBOctreeNodeChildID
	{
		MB_OCTREE_NODE_CHILD_ID_FTL = 0,
		MB_OCTREE_NODE_CHILD_ID_FTR = 1,
		MB_OCTREE_NODE_CHILD_ID_FBL = 2,
		MB_OCTREE_NODE_CHILD_ID_FBR = 3,
		MB_OCTREE_NODE_CHILD_ID_BTL = 4,
		MB_OCTREE_NODE_CHILD_ID_BTR = 5,
		MB_OCTREE_NODE_CHILD_ID_BBL = 6,
		MB_OCTREE_NODE_CHILD_ID_BBR = 7
	};
	/** Vector containing the minimum point of the octree node */
	MBVec3 mMin;
	/** Vector containing the maximum point of the octree node */
	MBVec3 mMax;
	/** Vector containing the mid-point [(max + min) / 2] of the octree node */
	MBVec3 mMidPoint;
	/** Side lengths of the cuboid shaped octree node */
	MBVec3 mSideLengths;
	/** Level of the octree node */
	MBuint mLevel;
	/** Maximum number of levels in the octree */
	MBuint mMaxLevels;
	/** The Children in an array with order: ftl, ftr, fbl, fbr, btl, btr, bbl, bbr
		(f-front, b-back, t-top, b-back/bottom, l-left, r-right) */
	MBOctreeNode **mChildren;
	/** The indices of the MBTriangle objects stored in this octree node */
	std::vector<MBuint> *mTriangleIndices;

 	void ManagePotentialTriangleIntersection(
		const MBVec3 *trianglePoints,
		const MBuint &triangleIndex,
		const MBVec3 &cuboidMin,
		const MBVec3 &cuboidMax,
		const MBOctreeNodeChildID &childID );
};